/*
 Exercise 5.2
 Binary Quiz Game
 Chapter Five @ http://www.tronixstuff.com/tutorials
*/


int seglatch = 13;
int segclock = 12;
int segdata = 11;
int ledlatch = 7;
int ledclock = 6;
int leddata = 5;
int speaker = 4;
int button = 2;

int possanswer=0;
int topscore = 0;
int currentscore = 0;

int currentnumber = 0;
int scrolldelay = 150;
int greeting1[] = {
  0,0,0,118,121,56,56,92,0,70,118,121,80,121,0,0,0,0,0,0}; // byte values for "Hello there"
int greeting2[] = {0,0,0,115,80,121,109,109,0,124,28,70,70,92,84,0,70,92,0,109,70,119,80,70,0,0,0,0,0,0}; // = Press button to start
int numbers[] = {
  63,6,91,79,102,109,125,7,127,111}; // bytes to display 0~9 on seven segment display
int greeting3[] = {0,0,0,109,88,92,80,121,0,0,0,0,0,0}; // "Score"
int greeting4[] = {0,0,0,70,92,115,0,109,88,92,80,121,0,0,0,0,0,0}; // "Top Score"
int rawreading = 0;
float rawdivided = 0;
int ldig = 0;
int mdig = 0;
int rdig = 0;
int finalread = 0;
float d = 0;
int c = 0;
float b = 0;
int e = 0;

void setup()
{
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(2, INPUT);
  Serial.begin(9600);
}

void startup()  // how to make it look at button 
{
   for (int q = 0; q<15; q++)
   {
    segdisplay(greeting1[q+2],greeting1[q+1],greeting1[q]);
    delay(scrolldelay);  
   }
   delay(600);
    for (int q = 0; q<25; q++)
   {
    segdisplay(greeting2[q+2],greeting2[q+1],greeting2[q]);
    delay(scrolldelay);  
   }
   waitforpress(button);
   Serial.write("startup() finished"); Serial.println(0);
   
}

void segdisplay(int lastchar, int midchar, int firstchar)
{
  digitalWrite(seglatch, LOW);
  shiftOut(segdata, segclock, MSBFIRST, lastchar);
  shiftOut(segdata, segclock, MSBFIRST, midchar);
  shiftOut(segdata, segclock, MSBFIRST, firstchar);
  digitalWrite(seglatch, HIGH); 
}

void waitforpress(int inputpin)
// function to stop and wait for user to press button on input 
// pin number 'inputpin'. Ensure this is set to input using
// pinMode(input, pin number)
{
  while (digitalRead(inputpin)==0)
  {
    delay(10); // 
  }
  delay(1000);; // debounce
}

void readdial()
// function to read the potentiometer, display the value between 0~255 on the display
// and once user has pressed the button, return the selected number as an integer
// pot analogue 5
{
  rawreading = analogRead(5);
  rawdivided = rawreading/4;
  finalread = int(rawdivided); // get the value of the potentiometer, convert it into 0~255
  if (finalread<10)
  {
    digitalWrite(seglatch, LOW);
    shiftOut(segdata, segclock, MSBFIRST, numbers[finalread]); // sends the digit down the serial path
    shiftOut(segdata, segclock, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
    shiftOut(segdata, segclock, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
    digitalWrite(seglatch, HIGH);
  }
  else if (finalread>=10 && finalread<100)
  {
    d=finalread%10; // find the remainder of dividing d by 10, this will be the right-hand digit
    c=int(d); // make it an integer, c is the right hand digit
    b=finalread/10; // divide z by 10 - the whole number value will be the left-hand digit
    e = int(b); // e is the left hand digit
    digitalWrite(seglatch, LOW); // send the digits down to the shift registers!
    shiftOut(segdata, segclock, MSBFIRST, numbers[c]); 
    shiftOut(segdata, segclock, MSBFIRST, numbers[e]); 
    shiftOut(segdata, segclock, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
    digitalWrite(seglatch, HIGH);
  }
  else if (finalread>=100)
  {
    b=finalread/100;
    ldig=int(b);  // left-hand digit
    b=finalread % 100;
    d=b/10;
    mdig=int(d);  // middle digit
    d=finalread%10;
    c=int(d); 
    b=finalread/10; 
    rdig=int(d); // right digit
    digitalWrite(seglatch, LOW); // send the digits down to the shift registers!
    shiftOut(segdata, segclock, MSBFIRST, numbers[rdig]); 
    shiftOut(segdata, segclock, MSBFIRST, numbers[mdig]); 
    shiftOut(segdata, segclock, MSBFIRST, numbers[ldig]); 
    digitalWrite(seglatch, HIGH);
  }

  if (digitalRead(2)==1) // if the button is pressed, return the value and end function
  {
    possanswer=finalread;
  }

}

void correctanswer()
// function to run if the user enters a correct answer
{
  currentscore++;
  digitalWrite(ledlatch, LOW); // turn off LEDs
  shiftOut(leddata, ledclock, MSBFIRST, 0); 
  digitalWrite(ledlatch, HIGH);
  segdisplay(109,121,110); // blink "YES" twice
  delay(500);
  segdisplay(0,0,0);
  delay(500);
  segdisplay(109,121,110);
  delay(500);
  segdisplay(0,0,0);
   for (int q = 0; q<9; q++)
   {
    segdisplay(greeting3[q+2],greeting3[q+1],greeting3[q]);
    delay(scrolldelay);  
   }
   delay(100);
    d=currentscore%10; // find the remainder of dividing d by 10, this will be the right-hand digit
    c=int(d); // make it an integer, c is the right hand digit
    b=finalread/10; // divide z by 10 - the whole number value will be the left-hand digit
    e = int(b); // e is the left hand digit
    digitalWrite(seglatch, LOW); // send the digits down to the shift registers!
    shiftOut(segdata, segclock, MSBFIRST, numbers[c]); 
    shiftOut(segdata, segclock, MSBFIRST, numbers[e]); 
    shiftOut(segdata, segclock, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
    digitalWrite(seglatch, HIGH);
    delay(500);
     for (int q = 0; q<9; q++)
   {
    segdisplay(greeting3[q+2],greeting3[q+1],greeting3[q]);
    delay(scrolldelay);  
   }
   delay(100);
    d=currentscore%10; // find the remainder of dividing d by 10, this will be the right-hand digit
    c=int(d); // make it an integer, c is the right hand digit
    b=finalread/10; // divide z by 10 - the whole number value will be the left-hand digit
    e = int(b); // e is the left hand digit
    digitalWrite(seglatch, LOW); // send the digits down to the shift registers!
    shiftOut(segdata, segclock, MSBFIRST, numbers[c]); 
    shiftOut(segdata, segclock, MSBFIRST, numbers[e]); 
    shiftOut(segdata, segclock, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
    digitalWrite(seglatch, HIGH);
    delay(500);
    segdisplay(0,0,0);
}
  
  
void incorrectanswer()
// function to run if the user enters an incorrect answer
{
  segdisplay(0,92,84); // blink "no" twice
  delay(500);
  segdisplay(0,0,0);
  delay(500);
  segdisplay(0,92,84);
  delay(500);
  segdisplay(0,6,109); // "is"
     b=finalread/100;
    ldig=int(b);  // left-hand digit
    b=finalread % 100;
    d=b/10;
    mdig=int(d);  // middle digit
    d=finalread%10;
    c=int(d); 
    b=finalread/10; 
    rdig=int(d); // right digit
    digitalWrite(seglatch, LOW); // send the digits down to the shift registers!
    shiftOut(segdata, segclock, MSBFIRST, numbers[rdig]); 
    shiftOut(segdata, segclock, MSBFIRST, numbers[mdig]); 
    shiftOut(segdata, segclock, MSBFIRST, numbers[ldig]); 
    digitalWrite(seglatch, HIGH);
    waitforpress(button);
    for (int q = 0; q<9; q++) // display "score"
   {
    segdisplay(greeting3[q+2],greeting3[q+1],greeting3[q]);
    delay(scrolldelay);  
   }
   delay(100);
    d=currentscore%10; // find the remainder of dividing d by 10, this will be the right-hand digit
    c=int(d); // make it an integer, c is the right hand digit
    b=finalread/10; // divide z by 10 - the whole number value will be the left-hand digit
    e = int(b); // e is the left hand digit
    digitalWrite(seglatch, LOW); // send the digits down to the shift registers!
    shiftOut(segdata, segclock, MSBFIRST, numbers[c]); 
    shiftOut(segdata, segclock, MSBFIRST, numbers[e]); 
    shiftOut(segdata, segclock, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
    digitalWrite(seglatch, HIGH);
    delay(500);
     for (int q = 0; q<9; q++) // display "score"
   {
    segdisplay(greeting3[q+2],greeting3[q+1],greeting3[q]);
    delay(scrolldelay);  
   }
   delay(100);
    d=currentscore%10; // find the remainder of dividing d by 10, this will be the right-hand digit
    c=int(d); // make it an integer, c is the right hand digit
    b=finalread/10; // divide z by 10 - the whole number value will be the left-hand digit
    e = int(b); // e is the left hand digit
    digitalWrite(seglatch, LOW); // send the digits down to the shift registers!
    shiftOut(segdata, segclock, MSBFIRST, numbers[c]); 
    shiftOut(segdata, segclock, MSBFIRST, numbers[e]); 
    shiftOut(segdata, segclock, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
    digitalWrite(seglatch, HIGH);
    delay(500);
    segdisplay(0,0,0);
}
  
void endgame()
{
  for (int q = 0; q<9; q++)
   {
    segdisplay(greeting3[q+2],greeting3[q+1],greeting3[q]);
    delay(scrolldelay);  
   }
   delay(100);
    d=currentscore%10; // find the remainder of dividing d by 10, this will be the right-hand digit
    c=int(d); // make it an integer, c is the right hand digit
    b=finalread/10; // divide z by 10 - the whole number value will be the left-hand digit
    e = int(b); // e is the left hand digit
    digitalWrite(seglatch, LOW); // send the digits down to the shift registers!
    shiftOut(segdata, segclock, MSBFIRST, numbers[c]); 
    shiftOut(segdata, segclock, MSBFIRST, numbers[e]); 
    shiftOut(segdata, segclock, MSBFIRST, 0); // sends a blank down the serial path to push the digit to the right
    digitalWrite(seglatch, HIGH);
    delay(500);
    if (currentscore>topscore)
    {
        topscore=currentscore;
        for (int q = 0; q<13; q++)
         {
            segdisplay(greeting3[q+2],greeting3[q+1],greeting3[q]);
            delay(scrolldelay);  
         }
         for (int q = 0; q<13; q++)
         {
            segdisplay(greeting3[q+2],greeting3[q+1],greeting3[q]);
            delay(scrolldelay);  
         }
    }
    startup();
}

void loop()
{
  startup();
  randomSeed(analogRead(3)); // seed the random number generator // put this within the loop of the main  game
  
  currentscore=0;
  for (int loopy=0; loopy<10; loopy++)
  {
    currentnumber=random(256);
    
    Serial.write("current number: ");
    Serial.print(currentnumber);
        Serial.write("loopy: ");
        Serial.println(loopy);
    
    
    
    digitalWrite(ledlatch, LOW); // send the digits down to the shift registers!
    shiftOut(leddata, ledclock, MSBFIRST, currentnumber); 
    digitalWrite(ledlatch, HIGH);
 Serial.write("sent random number to LEDs"); Serial.println(0);
    readdial;
    if (possanswer == currentnumber)
    {
        correctanswer();
    }
    else if (possanswer != currentnumber)
    {
        incorrectanswer();
    }
  }
  endgame();
}

